//! 中继类型的节点
//!
//!

use serde::{Deserialize, Serialize};
use std::{
    collections::HashMap,
    ops::{Deref, DerefMut},
};

use crate::{bean::node::base_node::BaseNode, error::Error};
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
pub struct RelayNode {
    #[serde(flatten)]
    base_node: BaseNode,
    hash: String,                             // 对应区块hash值(变更节点信息会更新)
    exchange_ratios: HashMap<String, String>, // 兑换比例
    address: HashMap<String, String>, // 中继节点各主链币种地址 key: INVE, BTC, ETH, SNC, value: 地址
    fee_ratio: f64,                   // 跨链交易手续费用(取值范围0.0 - 1.0, 精度小数点6位)
    register_timestamp: i64,          // 注册时间戳
    last_alive_timestamp: i64,        //上次更新时间戳
    name: String,                     // 节点名称
    phone: String,                    // 告警联系电话
    email: String,                    // 告警联系邮箱
}

impl RelayNode {
    pub fn new() -> RelayNodeBuilder {
        RelayNodeBuilder::default()
    }

    pub fn base_node(&self) -> &BaseNode {
        &self.base_node
    }

    pub fn hash(&self) -> &str {
        &self.hash
    }

    pub fn exchange_ratios(&self) -> &HashMap<String, String> {
        &self.exchange_ratios
    }

    pub fn address(&self) -> &HashMap<String, String> {
        &self.address
    }

    pub fn fee_ratio(&self) -> f64 {
        self.fee_ratio
    }

    pub fn register_timestamp(&self) -> i64 {
        self.register_timestamp
    }

    pub fn last_alive_timestamp(&self) -> i64 {
        self.last_alive_timestamp
    }

    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn phone(&self) -> &str {
        &self.phone
    }

    pub fn email(&self) -> &str {
        &self.email
    }

    pub fn set_base_node(&mut self, base_node: &BaseNode) {
        self.base_node = base_node.clone();
    }

    pub fn set_hash(&mut self, hash: &str) {
        self.hash = hash.to_string();
    }

    pub fn set_exchange_ratios(&mut self, exchange_ratios: &HashMap<String, String>) {
        self.exchange_ratios = exchange_ratios.clone();
    }

    pub fn set_address(&mut self, address: &HashMap<String, String>) {
        self.address = address.clone();
    }

    pub fn set_fee_ratio(&mut self, fee_ratio: f64) {
        self.fee_ratio = fee_ratio;
    }

    pub fn set_register_timestamp(&mut self, register_timestamp: i64) {
        self.register_timestamp = register_timestamp;
    }

    pub fn set_last_alive_timestamp(&mut self, last_alive_timestamp: i64) {
        self.last_alive_timestamp = last_alive_timestamp;
    }

    pub fn set_name(&mut self, name: &str) {
        self.name = name.to_string();
    }

    pub fn set_phone(&mut self, phone: &str) {
        self.phone = phone.to_string();
    }

    pub fn set_email(&mut self, email: &str) {
        self.email = email.to_string();
    }

    pub fn equals(&self, json: &str) -> Result<bool, Error> {
        let other: RelayNode = serde_json::from_str(json)?;
        Ok(self == &other)
    }

    pub fn check_if_alive_node(&self, interval: i64) -> bool {
        chrono::Local::now().timestamp() - self.last_alive_timestamp < interval
    }
}

impl Deref for RelayNode {
    type Target = BaseNode;

    fn deref(&self) -> &Self::Target {
        &self.base_node
    }
}

impl DerefMut for RelayNode {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.base_node
    }
}

#[derive(Debug, Clone, Default)]
pub struct RelayNodeBuilder {
    base_node: BaseNode,
    hash: String,                             // 对应区块hash值(变更节点信息会更新)
    exchange_ratios: HashMap<String, String>, // 兑换比例
    address: HashMap<String, String>, // 中继节点各主链币种地址 key: INVE, BTC, ETH, SNC, value: 地址
    fee_ratio: f64,                   // 跨链交易手续费用(取值范围0.0 - 1.0, 精度小数点6位)
    register_timestamp: i64,          // 注册时间戳
    last_alive_timestamp: i64,        //上次更新时间戳
    name: String,                     // 节点名称
    phone: String,                    // 告警联系电话
    email: String,                    // 告警联系邮箱
}

impl RelayNodeBuilder {
    pub fn set_base_node(&mut self, base_node: &BaseNode) -> &mut Self {
        self.base_node = base_node.clone();
        self
    }

    pub fn set_hash(&mut self, hash: &str) -> &mut Self {
        self.hash = hash.to_string();
        self
    }

    pub fn set_exchange_ratios(&mut self, exchange_ratios: &HashMap<String, String>) -> &mut Self {
        self.exchange_ratios = exchange_ratios.clone();
        self
    }

    pub fn set_address(&mut self, address: &HashMap<String, String>) -> &mut Self {
        self.address = address.clone();
        self
    }

    pub fn set_fee_ratio(&mut self, fee_ratio: f64) -> &mut Self {
        self.fee_ratio = fee_ratio;
        self
    }

    pub fn set_register_timestamp(&mut self, register_timetamp: i64) -> &mut Self {
        self.register_timestamp = register_timetamp;
        self
    }

    pub fn set_last_alive_timestamp(&mut self, last_alive_timestamp: i64) -> &mut Self {
        self.last_alive_timestamp = last_alive_timestamp;
        self
    }

    pub fn set_name(&mut self, name: &str) -> &mut Self {
        self.name = name.to_string();
        self
    }

    pub fn set_phone(&mut self, phone: &str) -> &mut Self {
        self.phone = phone.to_string();
        self
    }

    pub fn set_email(&mut self, email: &str) -> &mut Self {
        self.email = email.to_string();
        self
    }

    pub fn build(self) -> RelayNode {
        RelayNode {
            base_node: self.base_node,
            hash: self.hash,
            exchange_ratios: self.exchange_ratios,
            address: self.address,
            fee_ratio: self.fee_ratio,
            register_timestamp: self.register_timestamp,
            last_alive_timestamp: self.last_alive_timestamp,
            name: self.name,
            phone: self.phone,
            email: self.email,
        }
    }
}
